﻿using System;
using System.Runtime.InteropServices;

namespace StoCombatLogHUD.Toolkit
{
	/// <summary>
	/// This class tries to implement the stuff descibed here:
	/// <see cref="http://www.skymaster1980.net16.net/index.php/direct3d/advanced-code-snippets/253-external-directx-overlay-non-hooked-c-"/>
	/// Yet it fails to do so since the prerequisites are not met (window not configured correctly, e.g. "AlwaysOnTop" not set)
	/// </summary>
	public static class WindowHack
	{
		//this is used to specify the boundaries of the transparent area
		internal struct Margins
		{
			public int Left, Right, Top, Bottom;
		}

		[DllImport("user32.dll", SetLastError = true)]
		private static extern UInt32 GetWindowLongPtr(IntPtr hWnd, int nIndex);

		[DllImport("user32.dll", SetLastError = true)]
		private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

		[DllImport("user32.dll", SetLastError = true)]
		private static extern int SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);

		// ReSharper disable InconsistentNaming
		public const int GWL_EXSTYLE = -20;
		public const int WS_EX_LAYERED = 0x80000;
		public const int WS_EX_TRANSPARENT = 0x20;
		public const int LWA_ALPHA = 0x2;
		public const int LWA_COLORKEY = 0x1;
		// ReSharper restore InconsistentNaming

		[DllImport("dwmapi.dll")]
		private static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMargins);

		/// <summary>
		/// Applies the window overlay.
		/// </summary>
		/// <param name="windowHandle">The window handle.</param>
		/// <param name="width">The width.</param>
		/// <param name="height">The height.</param>
		public static void ApplyWindowOverlay(IntPtr windowHandle, int width, int height)
		{
			//Make the window's border completely transparent
			SetWindowLongPtr(windowHandle, GWL_EXSTYLE,
			                 (IntPtr)
			                 (GetWindowLongPtr(windowHandle, GWL_EXSTYLE) ^ WS_EX_LAYERED ^ WS_EX_TRANSPARENT));

			//Set the Alpha on the Whole Window to 255 (solid)
			SetLayeredWindowAttributes(windowHandle, 0, 255, LWA_ALPHA);

			//Create a margin (the whole form)
			var margins = new Margins
				              {
					              Left = 0,
					              Top = 0,
					              Right = width,
					              Bottom = height,
				              };

			//Expand the Aero Glass Effect Border to the WHOLE form.
			// since we have already had the border invisible we now
			// have a completely invisible window - apart from the OpenGL
			// renders NOT in black.
			DwmExtendFrameIntoClientArea(windowHandle, ref margins);
		}
	}
}
